package com.ruoyi.aitcommon.config;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.aitcommon.utils.ExceptionUtils;
import com.ruoyi.aitcommon.utils.MapUtils;

import java.util.HashSet;
import java.util.Map;
import java.util.Set;

public class ConfigUtils {
    public static void verifyConfig(String parm, Map<String,Object> configContext) throws Exception{
        if(parm.equals("appconfig.permissions.roles")){
            //角色验证
            final Object pathObject = MapUtils.getPathObject(parm, configContext);
            JSONArray roles=(JSONArray)pathObject;
            validateUniqueCode(roles,"code");//验证编码是否重复
            final Object userRolesObj = MapUtils.getPathObject(
                    "appconfig.permissions-copy.userRoles"
                    , configContext);
            validateCodeExists(roles,"code"
                    ,(JSONArray) userRolesObj,"roles");//校验编码是否存在于userRoles中
        } else if (parm.equals("appconfig.permissions.roles")) {
            //角色验证
            final Object pathObject = MapUtils.getPathObject(parm, configContext);
            JSONArray roles=(JSONArray)pathObject;
            validateUniqueCode(roles,"code");
            final Object roleUsersObj = MapUtils.getPathObject(
                    "appconfig.permissions.roleUsers"
                    , configContext);
            validateCodeExists(roles,"code"
                    ,(JSONArray) roleUsersObj,"role");
        }
    }

    /**
     * 验证编码是否存在。
     *
     * @param codeArray 需要被校验的集合，其中每个元素都是包含"code"属性的JSONObject。
     * @param codeContains 集合中包含的code，其中每个元素都是包含"code"属性的JSONObject。
     * @throws Exception 如果在codeContains中有任何一个code在codeArray中找不到，则抛出异常。
     */
    public static void validateCodeExists(JSONArray codeArray,String codeField
            , JSONArray codeContains,String codeField1) throws Exception {
        // 创建一个Set来存储codeArray中的所有code值
        Set<String> existingCodes = new HashSet<>();

        // 遍历codeArray并收集所有的code到Set中
        for (int i = 0; i < codeArray.size(); i++) {
            JSONObject item = codeArray.getJSONObject(i);
            if (item.containsKey(codeField)) {
                existingCodes.add(item.getString(codeField));
            } else {
                throw new Exception("JSONArray 'codeArray' contains an object without a '"+codeField+"' property.");
            }
        }

        // 检查codeContains中的每一个code是否都在existingCodes中
        ExceptionUtils.checkBlankOrUndefined(codeContains,"codeContains为空");
        for (int i = 0; i < codeContains.size(); i++) {
            JSONObject item = codeContains.getJSONObject(i);
            if (item.containsKey(codeField1)) {
                final Object codeToCheck = item.get(codeField1);
                if(codeToCheck instanceof String){
                    if (!existingCodes.contains(codeToCheck)) {
                        throw new Exception("编码 '" + codeToCheck + "' 已经被引用");
                    }
                }else if(codeToCheck instanceof JSONArray){
                    JSONArray codeToCheckArray = item.getJSONArray(codeField1);
                    for(Object codeToCheck1 : codeToCheckArray){
                        if (!existingCodes.contains(codeToCheck1)) {
                            throw new Exception("编码 '" + codeToCheck1 + "' 已经被引用");
                        }
                    }
                }
            } else {
                throw new Exception("JSONArray 'codeContains' contains an object without a '"+codeField1+"' property.");
            }
        }
    }
    /**
     * 校验JSONArray列表中的对象code属性是否重复。
     * @param jsonArray JSON数组
     * @return 如果没有重复的code属性返回true，否则返回false
     */
    public static void validateUniqueCode(JSONArray jsonArray,String codeField) throws Exception {
        Set<String> codes = new HashSet<>();
        for (int i = 0; i < jsonArray.size(); i++) {
            JSONObject jsonObject = jsonArray.getJSONObject(i);
            // Check if the object has a 'code' property
            if (!jsonObject.containsKey(codeField)) {
                throw new Exception("JSONObject at index " + i + " does not have a '"+codeField+"' property.");
            }
            String code = jsonObject.getString(codeField);
            // If the set already contains this code, it means there is a duplicate
            if (!codes.add(code)) { // add() returns false if the set did not change as a result of the call
                throw new Exception("编码重复: " + code);
            }
        }
    }
}
